package com.tsfyun.scm.gateway.config;

import cn.hutool.core.util.ArrayUtil;
import com.tsfyun.scm.gateway.config.properties.NoRequestLimitProperties;
import com.tsfyun.scm.gateway.config.properties.PermitUrlProperties;
import com.tsfyun.scm.gateway.constant.LimitConstant;
import com.tsfyun.scm.gateway.util.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.util.AntPathMatcher;
import reactor.core.publisher.Mono;

import java.util.Objects;

/**
 * @Description:
 * @CreateDate: Created in 2021/6/28 17:59
 */
@Slf4j
public class CustomKeyResolver {

    private PermitUrlProperties permitUrlProperties;

    private NoRequestLimitProperties noRequestLimitProperties;

    public CustomKeyResolver(final PermitUrlProperties permitUrlProperties,final NoRequestLimitProperties noRequestLimitProperties) {
        this.permitUrlProperties = permitUrlProperties;
        this.noRequestLimitProperties = noRequestLimitProperties;
    }

    private AntPathMatcher pathMatcher = new AntPathMatcher();

    public KeyResolver customKeyResolver() {
        KeyResolver keyResolver = exchange -> {
            String ip = IpUtils.getIpAddress(exchange.getRequest());
            String requestUrl = exchange.getRequest().getPath().value();
            String token = exchange.getRequest().getHeaders().getFirst("token");
            //免登录请求不做限流控制
            if (ArrayUtil.isNotEmpty(permitUrlProperties.getIgnored())) {
                for (String ignore : permitUrlProperties.getIgnored()) {
                    //通配符比较
                    if (pathMatcher.match(ignore, requestUrl)) {
                        log.warn("免登录请求，不做限流限制【{}】", requestUrl);
                        return Mono.just(LimitConstant.MDL_REQUEST_URL);
                    }
                }
            }
            //自定义不限流请求
            if (ArrayUtil.isNotEmpty(noRequestLimitProperties.getIgnored())) {
                for (String ignore : noRequestLimitProperties.getIgnored()) {
                    //通配符比较
                    if (pathMatcher.match(ignore, requestUrl)) {
                        log.warn("系统配置的不限流请求，不做限流限制【{}】", requestUrl);
                        return Mono.just(LimitConstant.NO_LIMIT_URL);
                    }
                }
            }
            //不限流请求后面直接拦截掉
            token = Objects.isNull(token) ? "" : token;
            String frequencyKey = ip + "-" + token + "-" + requestUrl;
            return Mono.just(frequencyKey);
        };
        return keyResolver;
    }

}
